home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGNG_C
/
C_WINDW.LZH
/
DBFEDIT.C
< prev
next >
Wrap
Text File
|
1987-12-28
|
14KB
|
424 lines
/* (c) Marietta Systems, Inc 1987
All rights reserved */
/*
* This program allows the viewing, amending, deleting and adding of
* records to a dBase II Plus '.dbf' file.
*
* This program only works with files with less than 21 fields!
*/
#include "mtest.h"
#ifndef LATTICE
#define memcpy memmove
#endif
/* */
#define fileend (FN[fh].start + FN[fh].rec_len * FN[fh].prime)
int dbf_acpt(int, int, struct DBF_DEF*, enum ATTRIB);
int dbf_disp(int, int, struct DBF_DEF*, enum ATTRIB, int, int);
int dbf_init(int*, struct DBF_DEF**);
void dbf_mnt(int, int, struct DBF_DEF*, long*);
void do_search(int, char*, long*);
void mnt_scrn(int, char*);
void recblank(int);
int rec_acpt(int, int, struct DBF_DEF*);
void rec_disp(int, int, struct DBF_DEF*);
void show_nbr(int, long);
int stsearch(char*, char*);
/*
*
* Function to accept a dbase3 field
*
*/
int dbf_acpt(fh, field, format, atb)
int fh, field;
struct DBF_DEF *format;
enum ATTRIB atb;{
int z, basept, ret, x = _CURSOR.X, y = _CURSOR.Y;
enum _JUST just;
char text[255];
/* Error check */
if (fh < 5 || fh > MAXFILES || field < 0
|| field > FN[fh].start/32 - 2)
{disp_err("Parameter error in dbf_acpt", 1001); return -10;}
/* Setup */
for (z = 0 , basept = 1 ; z < field ; basept += format[z++].dbf_len);
memcpy(text, &FN[fh].record[basept], format[field].dbf_len);
text[format[field].dbf_len] = 0; /* copy to entry area */
switch ((int)format[field].dbf_type){
case 'C': just = left; break;
case 'L': just = left; break;
case 'N': just = decimal; break;
case 'D': just = date;
if (text[0] == 32)
{text[10] = -80; text[11] = text[12] = 0;}
else {text[12] = (char)atoi(&text[6]); text[6] = 0;
text[11] = (char)atoi(&text[4]); text[4] = 0;
text[10] = (char)(atoi(text) - 1980);}
memcpy (text, &text[10], 3);
break;
default: disp_err("Cannot edit memo field", 1002);
return (INCHAR == ENTER ? 0 : 1);
}
/* perform accept */
re_enter: ret = accept(text, just, atb, format[field].dbf_dig,
format[field].dbf_dec);
if (ret < 0) return ret; /* Pass through error code from accept */
if (ret && INCHAR == CTL_ENT) return ret;
switch ((int)format[field].dbf_type){
case 'C': break;
case 'L': text[0] = toupper(text[0]);
if (text[0] != 'T' && text[0] != 'F')
{disp_err("Logical field type requires 'T' or 'F'", 1);
set_crsr(x,y); goto re_enter;}
display(text, x, y, ACC_DISP);
break;
case 'N': break;
case 'D': memcpy(&text[10], text, 3);
if (text[1] != 0) sprintf(text, "%4u%2u%2u",
1980 + text[10], (int)text[11], (int)text[12]);
else strcpy(text, " ");
}
memcpy(&FN[fh].record[basept],text, format[field].dbf_len);
return ret;
} /* end of function dbf_acpt */
/*
*
* Function to display a dbase3 field
*
*/
int dbf_disp(fh, field, format, atb , x, y)
int fh, field, x, y;
struct DBF_DEF *format;
enum ATTRIB atb;{
int z, basept;
char text[255];
/* Error check */
if (fh < 5 || fh > MAXFILES || field < 0
|| field > FN[fh].start/32 - 2)
{disp_err("Parameter error in dbf_disp", 1001); return -10;}
/* Setup */
for (z = 0 , basept = 1 ; z < field ; basept += format[z++].dbf_len);
memcpy(text, &FN[fh].record[basept], format[field].dbf_len);
text[format[field].dbf_len] = 0;
switch ((int)format[field].dbf_type){
case 'N': strcpy(&text[60], text);
justify(decimal, text, &text[60], format[field].dbf_dig,
format[field].dbf_dec);
break;
case 'D': if (text[0] == 32) /* Null date */
{text[10] = -80; text[11] = text[12] = 0;}
else {text[12] = (char)atoi(&text[6]); text[6] = 0;
text[11] = (char)atoi(&text[4]); text[4] = 0;
text[10] = (char)(atoi(text) - 1980);}
date_out(text, &text[10]);
break;
default: break;
}
/* perform display */
display(text, x, y, atb);
return 0;
} /* end function dbf_disp */
/*
*
* Function to read in file and data dictionary
*
*/
int dbf_init(fields, format)
int *fields;
struct DBF_DEF **format;{
int fh, z;
char name[51], text[25];
for (z = 0; z < 8 ; KEYMATCH[z++] = 0); /* suppress function keys */
disp_err("",1); /* force display of function keys */
/* test if already initialized */
strcpy(name,"dbftest.dbf");
/* obtain file name and setup format */
for (;;){
disp_msg("",0);
display("Enter dBase 3+ file name ", 20, 1, high);
if (accept(name, left, alt_reverse, 50, 0) < 0 || INCHAR == QUIT)
goodbye(0);
if ((fh = fileopen(name, dbase3, update)) < 0) continue;
if (!fh) {disp_err("File not found - try again", 1); continue;}
if (FN[fh].start < 65)
{disp_err("Not valid dBase3+ file",1); idleloop(18);}
if (FN[fh].fnext == NULL)
disp_err("Could not load data dictionary",1);
if (FN[fh].start < 65 || FN[fh].fnext == NULL)
{fileclos(fh); continue;}
break;
} /* end for loop */
mk_wndw(5,15, 15,65, "Display of file header information");
display((byte*)FN[fh].fname, 1, 2, high);
sprintf(text, "prime = %ld", FN[fh].prime);
display(text, 2, 2, high);
sprintf(text, "start = %d", FN[fh].start);
display(text, 3, 2, high);
sprintf(text, "rec_len= %d", FN[fh].rec_len);
display(text, 4, 2, high);
sprintf(text, "write = %c", FN[fh].write);
display(text, 5, 2, high);
sprintf(text, "ftype = %d", (int)FN[fh].ftype);
display(text, 6, 2, high);
if (FN[fh].fnext == NULL)
display("NULL pointer value in fnext", 7, 2, high);
else display("Data dictionary loaded", 7, 2, high);
display("<< Press ESC key to continue >>", 9, 5, low);
while (grabchar() != ESC) disp_err("Press ESC key", 1);
rm_wndw();
*fields = dbf_fld(fh);
*format = (struct DBF_DEF *)FN[fh].fnext;
return fh;
} /* end function dbf_init */
/*
*
* Function to initialize the screen
*
*/
void mnt_scrn(fh, title)
int fh;
char *title;{
/* setup function key map */
KEYMATCH[0] = 0X428; /* PgDn, Up arrow, Ctrl+Enter */
KEYMATCH[1] = 0X104; /* PgUp, Down arrow */
KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[6] = KEYMATCH[5] = 0;
KEYMATCH[4] = 0XB400; /* F3, F5, F6, F8 */
KEYMATCH[7] = 0X4800; /* Ctrl+PgDn, Ctrl+PgUp */
disp_err("",1); /* force display of new function keys */
/* Create info area at top of screen */
display("\030:Prev field PgUp:Prev Record Ctrl+PgUp:1st Record ",
1, 2, low);
display((byte*)FN[fh].fname, 1, 65, alt_low);
display("\031:Next field PgDn:Next Record Ctrl+PgDn:Last Record",
2, 2, low);
/* create edit window */
if (mk_wndw(TOP_LINE + 3, 1, SCRN_LEN, SCRN_WID, title) < 0)
goodbye(10);
} /* end function mnt_scrn */
/*
*
* Function to display a record on the screen
*
*/
void rec_disp(fh, fields, format)
int fh, fields;
struct DBF_DEF *format;{
int x = 1, z, len;
clr_wndw();
if (FN[fh].record[0] != IN_USE)
display("Record status is deleted", x++, 5, blink);
for (z = 0 ; z < fields ; z++){
display(format[z].dbf_name, x, 1, high);
dbf_disp(fh, z, format, reverse, x, 12);
len = (format[z].dbf_type != 'N' ? format[z].dbf_len :
fld_len(decimal, format[z].dbf_dig, format[z].dbf_dec));
x += len / (SCRN_WID - 12) + 1;
}
} /* end function rec_disp */
/*
*
* Function to accept a record on the screen
*
*/
int rec_acpt(fh, fields, format)
int fh, fields;
struct DBF_DEF *format;{
int x = 1, z, len, kk;
if (FN[fh].record[0] != IN_USE) x++;
for (z = 0 ; z < fields ; ){
set_crsr(x, 12);
if (dbf_acpt(fh, z, format, alt_reverse)) kk = INCHAR; else kk = 0;
switch (kk){
case 0:
case ENTER:
case CRS_DN:
len = (format[z].dbf_type != 'N' ? format[z].dbf_len :
fld_len(decimal, format[z].dbf_dig, format[z].dbf_dec));
x += len / (SCRN_WID - 12) + 1;
z++; break;
case CTL_ENT:
case CRS_UP: if (z == 0) break;
len = (format[z-1].dbf_type != 'N' ? format[z-1].dbf_len :
fld_len(decimal, format[z-1].dbf_dig,
format[z-1].dbf_dec));
x -= len / (SCRN_WID - 12) + 1;
z--; break;
default: return kk;
}
}
return 0;
} /* end function rec_acpt */
/*
*
* Function to show current record location on screen
* (uses reserved functions 'set_clr' and 'scrn_map'
*/
void show_nbr(fh, rec_nbr)
int fh;
long rec_nbr;{
char text[16];
set_clr(99, low); /* use error status color */
sprintf(text, "%5lu of %-5lu", rec_nbr, FN[fh].prime);
scrn_map(text, TOP_LINE + 2, 65); /* hairy technique */
set_clr(98, low); /* reset color */
}
/*
*
* Function to blank out a record
*
*/
void recblank(fh)
int fh;{
memset(FN[fh].record, 32, FN[fh].rec_len);
FN[fh].record[FN[fh].rec_len] = 0;
FN[fh].record[0] = IN_USE;
}
/*
*
* Find if string2 is in string1
*
*/
int stsearch(s1, s2)
char *s1, *s2;{
int len2 = strlen(s2);
char *ptr;
ptr = strchr(s1, s2[0]);
while (ptr != NULL) {
if (!strncmp(ptr, s2, len2)) return 1; /* found */
ptr = strchr(&ptr[1], s2[0]);
}
return 0;
}
/*
*
* Function to search for a specified string
*
*/
void do_search(fh, text, rec_nbr)
char *text;
int fh;
long *rec_nbr;{
int count = 0;
long base = *rec_nbr;
char out[15];
/* setup */
if (mk_wndw(5,7, 11,73, "File search through dbase3+ file") < 0)
return;
display("Remember dates are stored as yyyymmdd ('19801231' for 12/31/80)",
5, 2, low);
/* obtain search text */
display("Enter search text ", 1, 1, high);
if (accept(text, left, alt_reverse, 16, 0))
{disp_err("Search abandoned",1); rm_wndw(); return;}
concat(text, 0); /* suppress trailing spaces */
strupr(text);
/* read around through the file */
for (;;) {
if (!fileread(fh, nextrec, rec_nbr))
fileread(fh, firstrec, rec_nbr);
if (*rec_nbr == base) {disp_err("No matching text found", 1);
warble(500); idleloop(5); rm_wndw(); warble(0); return;}
if (5 == (count++)) {
sprintf(out,"Record = %6lu", *rec_nbr);
display(out, 2, 5, reverse);
if (kbhit() && disp_qry("Do you wish to stop the search"))
{rm_wndw(); return;}
count = 0;
}
strupr(&FN[fh].record[1]);
if (stsearch(&FN[fh].record[1], text))
{disp_err("Match found", 1); *rec_nbr -= 1L;
rm_wndw(); return;}
}
}
/*
*
* Function to perform file maintenance
*
*/
void dbf_mnt(fh, fields, format, rec_nbr)
int fh, fields;
long *rec_nbr;
struct DBF_DEF *format;{
int ret;
byte kk = 0;
char text[17];
/* setup */
mnt_scrn(fh, "Edit function for dBase3+ files");
if ((ret = fileread(fh, firstrec, rec_nbr)) < 0) goodbye(3);
show_nbr(fh, *rec_nbr - 1L);
text[0] = 0;
if (!ret) kk = INSERT; /* Handle special case of empty file */
/* main accept loop */
for (;;){
if (!ret && !kk) recblank(fh);
if (!kk) {rec_disp(fh, fields, format); scrnsave(0);}
switch((kk ? kk : grabchar())){
case PGUP:
case CTL_ENT: kk = 0; *rec_nbr -= 2L;
if (*rec_nbr < 1L)
{*rec_nbr = 1L; disp_err("Top of file",1);}
break;
case PGDN:
case ENTER: kk = 0;
if (*rec_nbr > FN[fh].prime)
{*rec_nbr = FN[fh].prime; disp_err("End of file", 1);}
break;
case CTL_PGUP: *rec_nbr = 1L; kk = 0; break;
case CTL_PGDN: *rec_nbr = FN[fh].prime; kk = 0; break;
case UNDO: *rec_nbr -= 1L;
if (FN[fh].record[0] != DELETED ||
!disp_qry("Do you want to UNDO the delete"))
{kk = 0; break;}
FN[fh].record[0] = IN_USE;
if (filewrit(fh, rec_nbr) < 0) goodbye(6);
kk = 0; *rec_nbr -= 1L; break;
case SEARCH: do_search(fh, text, rec_nbr);
kk = 0; break;
case INSERT: fileseek(fh, fileend);
*rec_nbr = FN[fh].prime + 1L;
recblank(fh);
rec_disp(fh, fields, format);
kk = rec_acpt(fh, fields, format);
if (filewrit(fh, rec_nbr) < 0) goodbye(7);
if (!kk && *rec_nbr > FN[fh].prime) kk = INSERT;
break;
case DELETE: *rec_nbr -= 1L; kk = 0;
if (!disp_qry("Do you really want to delete")) break;
FN[fh].record[0] = DELETED;
if (filewrit(fh, rec_nbr) < 0) goodbye(8);
*rec_nbr -= 1L; break;
case AMEND: *rec_nbr -= 1L;
if (FN[fh].record[0] != IN_USE)
{disp_err("You cannot amend a deleted record",1);
kk = 0; break;}
kk = rec_acpt(fh, fields, format);
if (filewrit(fh, rec_nbr) < 0) goodbye(9);
break;
case QUIT: return;
case HELP: helpscrn(NULL);
default: disp_msg("",0); *rec_nbr -= 1L; kk = 0;
warble(1000); idleloop(ERR_BEEP); warble(0);
break;
} /* end switch */
if (kk && *rec_nbr) *rec_nbr -= 1L;
if ((ret = fileread(fh, relative, rec_nbr)) < 0) goodbye(5);
if (!ret) {disp_err("End of file reached",1);
ret = fileread(fh, lastrec, rec_nbr);}
show_nbr(fh, *rec_nbr - 1L);
} /* end for loop */
} /* end of dbf_mnt function */
/*
*
* Main program
*
*/
void main(){
struct DBF_DEF *format;
long rec_nbr = 1L;
int fh, fields;
clr_scrn("Test of dbf access");
if ((fh = dbf_init(&fields, &format)) < 1) goodbye(2);
dbf_mnt(fh, fields, format, &rec_nbr);
fileclos(fh);
goodbye(0);
}